package com.xiaoran.service.connector;

import com.xiaoran.service.config.ServerValue;
import com.xiaoran.common.utils.SpringBeanFactory;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RpcServerAcceptor implements Runnable {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(RpcServerAcceptor.class);

    private EventLoopGroup boss = new NioEventLoopGroup();
    private EventLoopGroup worker = new NioEventLoopGroup();
    ServerValue serverValue;
    RpcServerInitializer rpcServerInitializer;

    public RpcServerAcceptor() {
        serverValue = SpringBeanFactory.getBean(ServerValue.class);
        rpcServerInitializer = SpringBeanFactory.getBean(RpcServerInitializer.class);
    }

    @Override
    public void run() {
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(boss, worker)
                .channel(NioServerSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.DEBUG))
                .option(ChannelOption.SO_BACKLOG, 1024)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(rpcServerInitializer);
        try {
            LOGGER.info("ZnsServer acceptor startup at port[{}] successfully", serverValue.getNetworkPort());
            ChannelFuture future = serverBootstrap.bind(serverValue.getNetworkPort()).sync();
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            LOGGER.error("ZnsServer acceptor startup failure!", e);
            e.printStackTrace();
        }finally {
            boss.shutdownGracefully().syncUninterruptibly();
            worker.shutdownGracefully().syncUninterruptibly();
        }
    }
}
